package com.ruoyi.zq.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.zq.domin.ZqEntryBlank;
import com.ruoyi.common.zq.domin.ZqVolunteerActivity;
import com.ruoyi.common.zq.domin.vo.EntryBlankVO;
import com.ruoyi.common.zq.enums.SubscriberType;
import com.ruoyi.common.zq.mapper.EntryBlankMapper;
import com.ruoyi.zq.domin.dto.GradeDTO;
import com.ruoyi.zq.domin.dto.ZqNoticeDTO;
import com.ruoyi.zq.service.EntryBlankService;
import com.ruoyi.zq.service.VolunteerActivityService;
import com.ruoyi.zq.service.VolunteerTimeService;
import com.ruoyi.zq.service.ZqNoticeService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.rowset.serial.SerialException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 志愿活动报名
 *
 * @Author: LoneyFeather
 * @Date: Created in 14:13 2021/12/28
 */
@Slf4j
@Service
public class EntryBlankServiceImpl extends ServiceImpl<EntryBlankMapper, ZqEntryBlank> implements EntryBlankService {
    private static final Logger logger = LoggerFactory.getLogger(EntryBlankServiceImpl.class);

    @Autowired
    private EntryBlankMapper entryBlankMapper;

    @Autowired
    private VolunteerTimeService volunteerTimeService;

    @Autowired
    private VolunteerActivityService activityService;

    @Autowired
    private ZqNoticeService zqNoticeService;

    /**
     * 志愿者自己取消报名
     * @param entryBlankDTO
     * @return
     * @throws SerialException
     */
    @Override
    public int cancelByEntity(ZqEntryBlank entryBlankDTO) throws SerialException {
        ZqEntryBlank ob = entryBlankMapper.selectById(entryBlankDTO.getId());
        if(Objects.isNull(ob)){
            throw new ServiceException("数据错误");
        }
        if(ob.getPitchOn() == 1){
            // 进行消息通知发布人
            ZqVolunteerActivity activity = activityService.getById(ob.getActivityId());
            ZqNoticeDTO noticeDTO = new ZqNoticeDTO();
            noticeDTO.setNoticeTitle("志愿者（"+ SecurityUtils.getUsername() +"）取消报名");
            noticeDTO.setNoticeContent("希望活动发布者和志愿者确认后，做出相应的调整，以免对活动的顺利进行造成影响！！！");
            noticeDTO.setSubscriberType(SubscriberType.ALONE.name());
            noticeDTO.setStatus("0");
            noticeDTO.setNoticeType("1");
            noticeDTO.setCreateBy(SecurityUtils.getUsername());
            noticeDTO.setCreateTime(new Date());
            //添加单独接收人的id
            noticeDTO.setUserIds(new Long[]{activity.getCreateUserId()});
            zqNoticeService.addNoticeAndDetails(noticeDTO);
            logger.info("志愿者取消报名，已对发布者发出通知{}",noticeDTO.toString());

            throw new ServiceException("已经被选中，无法取消报名，如有必要，请联系发布人员进行删除操作");
        }
        ob =getObject(ob);
        ob.setPitchOn(entryBlankDTO.getPitchOn());

        return entryBlankMapper.updateById(ob);
    }



    @Override
    public int applyByPitchOn(ZqEntryBlank entryBlankDTO) throws SerialException {
        int num = 0;
        switch (entryBlankDTO.getPitchOn()){
            case 0:
                entryBlankDTO.setUserName(SecurityUtils.getUsername());
                num = addByEntity(entryBlankDTO);
                break;
            case -1:
                num = cancelByEntity(entryBlankDTO);
                break;
            case 1:
                num = pitchOnByModel(entryBlankDTO);
                break;
            default:
                throw new ServiceException("输入参数有错");
        }
        return num;
    }

    @Override
    public List<EntryBlankVO> listByActivityId(Long activityId) {
        List<ZqEntryBlank> list = entryBlankMapper.selectList(new LambdaQueryWrapper<ZqEntryBlank>()
                .eq(ZqEntryBlank::getActivityId,activityId)
//        .eq(ZqEntryBlank::getPitchOn,pitchOn)
        .eq(ZqEntryBlank::getIsDel,0));

        List<EntryBlankVO> blankList = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("###.0");
        for (ZqEntryBlank ob:list) {
            EntryBlankVO vo =new EntryBlankVO();
            BeanUtils.copyProperties(ob,vo);
            vo.setAgvGrade(entryBlankMapper.agvGrade(ob.getUserId()));
            blankList.add(vo);
        }

        return blankList;
    }

    @Override
    public int gradeByModel(GradeDTO gradeDTO) {
        ZqEntryBlank entryBlank = entryBlankMapper.selectOne(new LambdaQueryWrapper<ZqEntryBlank>()
            .eq(ZqEntryBlank::getActivityId,gradeDTO.getActivityId())
            .eq(ZqEntryBlank::getUserId,gradeDTO.getUserId())
            .eq(ZqEntryBlank::getIsDel,0));
        if (Objects.isNull(entryBlank)){
            throw new ServiceException("数据错误");
        }
        entryBlank = getObject(entryBlank);
        entryBlank.setGrade(gradeDTO.getGrade());
        entryBlank.setComment(gradeDTO.getComment());
        //添加服务时长
        int a = volunteerTimeService.addVolunteerTime(gradeDTO.getUserId(),gradeDTO.getTime(),entryBlank.getVolunteerTime());
        if (a <= 0){
            throw new ServiceException("添加志愿服务时长出错");
        }
        entryBlank.setVolunteerTime(gradeDTO.getTime());
        return entryBlankMapper.updateById(entryBlank);
    }

    @Override
    public ZqEntryBlank updateOnModel(Long activityId, Long userId) {
        ZqEntryBlank ob = entryBlankMapper.selectOne(new LambdaQueryWrapper<ZqEntryBlank>()
        .eq(ZqEntryBlank::getActivityId,activityId)
        .eq(ZqEntryBlank::getUserId,userId)
        .eq(ZqEntryBlank::getIsDel,0));
        ob = getObject(ob);
        ob.setPitchOn(1);
        return ob;
    }

    @Override
    public ZqEntryBlank getInfo(ZqEntryBlank entryBlankDTO) {
        ZqEntryBlank entryBlank = new ZqEntryBlank();
        entryBlank= entryBlankMapper.selectOne(new LambdaQueryWrapper<ZqEntryBlank>()
        .eq(ZqEntryBlank::getActivityId,entryBlankDTO.getActivityId())
                .eq(ZqEntryBlank::getUserId,entryBlankDTO.getUserId())
        .eq(ZqEntryBlank::getIsDel,0));
        return entryBlank;
    }

    @Override
    public int updatePitchOnByActivityId(Long activityId) {
        return entryBlankMapper.updatePitchOnByActivityId(activityId);
    }


    @Override
    public List<EntryBlankVO> listEntryBlank(ZqEntryBlank zqEntryBlankDTO) {
        return entryBlankMapper.listByDTO(zqEntryBlankDTO);
    }


    /**
     * 被选中
     * @param entryBlank
     * @return
     */
    private int pitchOnByModel(ZqEntryBlank entryBlank){
        ZqEntryBlank ob = entryBlankMapper.selectById(entryBlank.getId());
        if(Objects.isNull(ob)){
            throw new ServiceException("数据错误");
        }
        if(ob.getPitchOn() == -1){
            throw new ServiceException("用户已取消报名");
        }
        ob = getObject(ob);
        ob.setPitchOn(entryBlank.getPitchOn());

        // 添加通知(通知志愿者)。
        ZqVolunteerActivity activity = activityService.getById(ob.getActivityId());

        ZqNoticeDTO noticeDTO = zqNoticeService.getNoticePithOnTelephone(activity.getActivityName());
        noticeDTO.setUserIds(new Long[]{ob.getUserId()});
        zqNoticeService.addNoticeAndDetails(noticeDTO);
        logger.info("志愿入选通知：{}",noticeDTO.toString());


        return entryBlankMapper.updateById(ob);
    }




    /**
     * 某些通用的一些参数进入
     * @param DTO
     * @return
     */
    private ZqEntryBlank getObject(ZqEntryBlank DTO){
        ZqEntryBlank ob =DTO;
        ob.setUpdateTime(new Date());
        ob.setCreateBy(SecurityUtils.getUsername());
        return ob;
    }

    /**
     * 报名
     * @param entryBlank
     * @return
     */
    public int addByEntity(ZqEntryBlank entryBlank) {
        ZqEntryBlank ob = entryBlankMapper.selectOne(new LambdaQueryWrapper<ZqEntryBlank>()
                .eq(ZqEntryBlank::getActivityId,entryBlank.getActivityId())
                .eq(ZqEntryBlank::getUserId,entryBlank.getUserId()));
        if (Objects.isNull(ob)){
            ob =entryBlank;
            ob.setCreateBy(SecurityUtils.getUsername());
            ob.setCreateTime(new Date());
            ob = getObject(ob);
            // 需要知道，ob添加过后，id进去没
            entryBlankMapper.insert(ob);
        }
        ob.setIsDel(0);
        ob.setPitchOn(0);
        ob =getObject(ob);

        return entryBlankMapper.updateById(ob);
    }
}
